/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.codec;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

import com.jianggujin.codec.util.JCodecUtils;

/**
 * DSA-Digital Signature Algorithm
 * 是Schnorr和ElGamal签名算法的变种，被美国NIST作为DSS(DigitalSignature
 * Standard)。简单的说，这是一种更高级的验证方式，用作数字签名。不单单只有公钥、私钥，还有数字签名。私钥加密生成数字签名，公钥验证数据及签名。
 * 如果数据和签名不匹配则认为验证失败！数字签名的作用就是校验数据在传输过程中不被修改。数字签名，是单向加密的升级！
 * 
 * @author jianggujin
 *
 */
public class JDSA {
   public static final String ALGORITHM = "DSA";

   /**
    * DSA签名算法
    * 
    * @author jianggujin
    *
    */
   public static enum JDSASignatureAlgorithm {
      SHA1withDSA, SHA224withDSA, SHA256withDSA;
      public String getName() {
         return this.name();
      }
   }

   /**
    * 初始化密钥
    * 
    * @return
    */
   public static KeyPair initKey() {
      return initKey(1024);
   }

   /**
    * 初始化密钥
    * 
    * @param keySize
    * @return
    */
   public static KeyPair initKey(int keySize) {
      return JCodecUtils.initKey(ALGORITHM, keySize);
   }

   /**
    * 签名
    * 
    * @param data
    * @param privateKey
    * @param signatureAlgorithm
    * @return
    */
   public static byte[] sign(byte[] data, byte[] privateKey, JDSASignatureAlgorithm signatureAlgorithm) {
      return sign(data, privateKey, signatureAlgorithm.getName());
   }

   /**
    * 签名
    * 
    * @param data
    * @param privateKey
    * @param signatureAlgorithm
    * @return
    */
   public static byte[] sign(byte[] data, byte[] privateKey, String signatureAlgorithm) {
      PrivateKey priKey = JCodecUtils.getPrivateKey(privateKey, ALGORITHM);
      return sign(data, priKey, signatureAlgorithm);
   }

   /**
    * 签名
    * 
    * @param data
    * @param privateKey
    * @param signatureAlgorithm
    * @return
    */
   public static byte[] sign(byte[] data, PrivateKey privateKey, JDSASignatureAlgorithm signatureAlgorithm) {
      return sign(data, privateKey, signatureAlgorithm.getName());
   }

   /**
    * 签名
    * 
    * @param data
    * @param privateKey
    * @param signatureAlgorithm
    * @return
    */
   public static byte[] sign(byte[] data, PrivateKey privateKey, String signatureAlgorithm) {
      return JCodecUtils.sign(data, privateKey, signatureAlgorithm);
   }

   /**
    * 验签
    * 
    * @param data
    * @param sign
    * @param publicKey
    * @param signatureAlgorithm
    * @return
    */
   public static boolean verify(byte[] data, byte[] sign, byte[] publicKey, JDSASignatureAlgorithm signatureAlgorithm) {
      return verify(data, sign, publicKey, signatureAlgorithm.getName());
   }

   /**
    * 验签
    * 
    * @param data
    * @param sign
    * @param publicKey
    * @param signatureAlgorithm
    * @return
    */
   public static boolean verify(byte[] data, byte[] sign, byte[] publicKey, String signatureAlgorithm) {
      PublicKey pubKey = JCodecUtils.getPublicKey(publicKey, ALGORITHM);
      return verify(data, sign, pubKey, signatureAlgorithm);
   }

   /**
    * 验签
    * 
    * @param data
    * @param sign
    * @param publicKey
    * @param signatureAlgorithm
    * @return
    */
   public static boolean verify(byte[] data, byte[] sign, PublicKey publicKey,
         JDSASignatureAlgorithm signatureAlgorithm) {
      return verify(data, sign, publicKey, signatureAlgorithm.getName());
   }

   /**
    * 验签
    * 
    * @param data
    * @param sign
    * @param publicKey
    * @param signatureAlgorithm
    * @return
    */
   public static boolean verify(byte[] data, byte[] sign, PublicKey publicKey, String signatureAlgorithm) {
      return JCodecUtils.verify(data, sign, publicKey, signatureAlgorithm);
   }

}
